package com.cx.auth.config;

import com.cx.auth.AuthConstant;
import com.cx.auth.UserTokenService;
import com.cx.common.restful.BaseResult;
import com.cx.common.restful.ResultCode;
import com.cx.common.utils.JsonUtils;
import com.cx.po.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.*;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

/**
 * 统一定义security的处理器
 * Author:CHENXIAOYI
 * Since:2020/12/25 15:45
 */
@Slf4j
public class SecurityHandlerConfig {


    @Autowired
    private UserTokenService<SysUser> userUserTokenService;

    /*
        登陆失败处理器
     */
    @Bean
    public AuthenticationFailureHandler failureHandler(){
        return (request, response, e) -> {
            log.info("登录失败---" );
            String msg = "";
            if (e instanceof UsernameNotFoundException) {
                msg = e.getMessage();//"账号名输入错误!";
            } else if (e instanceof BadCredentialsException) {
                msg = "您的密码输入错误！";
            } else if (e instanceof LockedException) {
                msg = "您的账号已被锁定，请联系管理员!";
            } else if (e instanceof CredentialsExpiredException) {
                msg = "您的密码已过期，请联系管理员!";
            } else if (e instanceof AccountExpiredException) {
                msg = "您的账号已过期，请联系管理员!";
            } else if (e instanceof DisabledException) {
                msg = "您的账号已被禁用，请联系管理员!";
            } else {
                log.error("unknown login failed reason", e);
                msg = ResultCode.UNAUTHENTICATED_MSG.getMessage();
            }
            log.info("[{},{}] {}", request.getParameter(AuthConstant.USER_NAME), request.getRemoteAddr(), msg);
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(JsonUtils.object2String(BaseResult.error(msg)));

        };
    }

    /**
     * 登陆成功处理器
     * 回写登陆对象+请求头 token
     */
    @Bean
    public AuthenticationSuccessHandler successHandler(){
        return (request, response, authentication) -> {
            BaseResult<?> result;
            Object principal = authentication.getPrincipal();
            if( principal instanceof SysUser){
                SysUser sysUser = (SysUser) principal;
                String jwtToken = userUserTokenService.createAccessToken(sysUser);
                response.addHeader(AuthConstant.AUTHORIZATION, AuthConstant.BEARER + jwtToken);
                result = BaseResult.success(sysUser);
            }else{
                result = BaseResult.error(ResultCode.UNAUTHENTICATED);
            }
//            log.info("[{},{}] logged in", request.getParameter(SecurityConst.LOGIN_USERNAME_PARAM), RequestUtil.getRealIp(req));
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(JsonUtils.object2String(result));
        };

    }


    /**
     * 登出成功处理器
     */
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler(){
        return (request, response, authentication) -> {
            log.info("登出成功："+JsonUtils.object2String(authentication.getPrincipal()) );
        };
    }



}
